/**
 * instanceof 运算符详细教程
 * 用途：测试对象是否是某个构造函数的实例，或者通过原型链继承自该构造函数
 * 语法：object instanceof constructor
 */

console.log("======= instanceof 运算符详细教程 =======\n");

// 1. 基本数据类型 vs 对象类型
console.log("1. 基本数据类型 vs 对象类型：");
console.log("typeof 'hello':", typeof 'hello');
console.log("'hello' instanceof String:", 'hello' instanceof String); // false，基本字符串不是 String 对象的实例
console.log("new String('hello') instanceof String:", new String('hello') instanceof String); // true

console.log("typeof 42:", typeof 42);
console.log("42 instanceof Number:", 42 instanceof Number); // false
console.log("new Number(42) instanceof Number:", new Number(42) instanceof Number); // true

console.log("typeof true:", typeof true);
console.log("true instanceof Boolean:", true instanceof Boolean); // false
console.log("new Boolean(true) instanceof Boolean:", new Boolean(true) instanceof Boolean); // true
console.log();

// 2. 复杂数据类型
console.log("2. 复杂数据类型：");

// 数组
const arr = [1, 2, 3];
console.log("arr instanceof Array:", arr instanceof Array); // true
console.log("arr instanceof Object:", arr instanceof Object); // true，数组也是对象

// 对象
const obj = { name: 'test' };
console.log("obj instanceof Object:", obj instanceof Object); // true

// 函数
function testFunc() {}
console.log("testFunc instanceof Function:", testFunc instanceof Function); // true
console.log("testFunc instanceof Object:", testFunc instanceof Object); // true，函数也是对象

// 日期
const date = new Date();
console.log("date instanceof Date:", date instanceof Date); // true
console.log("date instanceof Object:", date instanceof Object); // true
console.log();

// 3. 自定义构造函数和原型链
console.log("3. 自定义构造函数和原型链：");

// 定义一个构造函数
function Person(name, age) {
  this.name = name;
  this.age = age;
}

// 创建实例
const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);

// 检查实例关系
console.log("person1 instanceof Person:", person1 instanceof Person); // true
console.log("person2 instanceof Person:", person2 instanceof Person); // true
console.log("person1 instanceof Object:", person1 instanceof Object); // true

// 直接使用对象字面量创建的对象不是 Person 的实例
const plainObj = { name: 'Charlie', age: 35 };
console.log("plainObj instanceof Person:", plainObj instanceof Person); // false
console.log();

// 4. 继承关系中的 instanceof
console.log("4. 继承关系中的 instanceof：");

// 定义父类
function Animal(name) {
  this.name = name;
}

// 定义子类
function Dog(name, breed) {
  Animal.call(this, name); // 调用父类构造函数
  this.breed = breed;
}

// 设置原型链实现继承
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog; // 修复构造函数指向

// 创建实例
const myDog = new Dog('Rex', 'German Shepherd');

// 检查继承关系
console.log("myDog instanceof Dog:", myDog instanceof Dog); // true
console.log("myDog instanceof Animal:", myDog instanceof Animal); // true
console.log("myDog instanceof Object:", myDog instanceof Object); // true

const myAnimal = new Animal('Generic Animal');
console.log("myAnimal instanceof Animal:", myAnimal instanceof Animal); // true
console.log("myAnimal instanceof Dog:", myAnimal instanceof Dog); // false，父类实例不是子类的实例
console.log();

// 5. ES6 类语法中的 instanceof
console.log("5. ES6 类语法中的 instanceof：");

class Vehicle {
  constructor(brand) {
    this.brand = brand;
  }
}

class Car extends Vehicle {
  constructor(brand, model) {
    super(brand);
    this.model = model;
  }
}

const myCar = new Car('Toyota', 'Camry');

console.log("myCar instanceof Car:", myCar instanceof Car); // true
console.log("myCar instanceof Vehicle:", myCar instanceof Vehicle); // true
console.log("myCar instanceof Object:", myCar instanceof Object); // true
console.log();

// 6. 异常处理中的 instanceof 应用（与项目相关）
console.log("6. 异常处理中的 instanceof 应用：");

// 模拟我们项目中的异常类结构
class BaseException extends Error {
  constructor(message, status = 500, errorCode = 50000, details) {
    super(message);
    this.name = this.constructor.name;
    this.status = status;
    this.errorCode = errorCode;
    this.details = details;
  }
}

class BadRequestException extends BaseException {
  constructor(message = '请求参数错误', errorCode = 40000, details) {
    super(message, 400, errorCode, details);
  }
}

class NotFoundException extends BaseException {
  constructor(message = '资源不存在', errorCode = 40400, details) {
    super(message, 404, errorCode, details);
  }
}

// 模拟异常抛出和捕获
function processRequest(requestType) {
  if (requestType === 'invalid') {
    throw new BadRequestException('参数验证失败', 40001, { field: 'email', message: '邮箱格式不正确' });
  } else if (requestType === 'missing') {
    throw new NotFoundException('用户不存在', 40401, { userId: 123 });
  } else if (requestType === 'error') {
    throw new Error('未知错误');
  }
  return '请求处理成功';
}

// 测试不同类型的异常处理
const testCases = ['valid', 'invalid', 'missing', 'error'];

testCases.forEach(testCase => {
  console.log(`\n测试 ${testCase} 请求:`);
  try {
    const result = processRequest(testCase);
    console.log('结果:', result);
  } catch (error) {
    // 使用 instanceof 判断异常类型，这与我们项目中的 ErrorHandler 类似
    if (error instanceof BaseException) {
      console.log(`捕获到自定义异常: ${error.name}`);
      console.log(`- 状态码: ${error.status}`);
      console.log(`- 错误码: ${error.errorCode}`);
      console.log(`- 错误消息: ${error.message}`);
      console.log(`- 错误详情:`, error.details);
      
      // 可以根据具体类型进行更细粒度的处理
      if (error instanceof BadRequestException) {
        console.log('- 特殊处理: 这是一个请求参数错误');
      } else if (error instanceof NotFoundException) {
        console.log('- 特殊处理: 这是一个资源不存在错误');
      }
    } else {
      // 处理非自定义异常
      console.log(`捕获到系统异常: ${error.name}`);
      console.log(`- 错误消息: ${error.message}`);
    }
  }
});

// 7. 边界情况和注意事项
console.log("\n7. 边界情况和注意事项：");

// null 和 undefined 不是任何构造函数的实例
console.log("null instanceof Object:", null instanceof Object); // false
console.log("undefined instanceof Object:", undefined instanceof Object); // false

// 修改原型会影响 instanceof 的结果
function TestClass() {}
const testObj = new TestClass();
console.log("原始 testObj instanceof TestClass:", testObj instanceof TestClass); // true

// 修改原型后
TestClass.prototype = {};
console.log("修改原型后 testObj instanceof TestClass:", testObj instanceof TestClass); // false

// 重写 Symbol.hasInstance 可以自定义 instanceof 行为
class CustomClass {
  static [Symbol.hasInstance](instance) {
    // 自定义判断逻辑，这里判断对象是否有特定属性
    return instance && typeof instance === 'object' && 'specialProperty' in instance;
  }
}

const objWithSpecial = { specialProperty: true };
const regularObj = { normalProperty: true };

console.log("objWithSpecial instanceof CustomClass:", objWithSpecial instanceof CustomClass); // true
console.log("regularObj instanceof CustomClass:", regularObj instanceof CustomClass); // false

console.log("\n======= instanceof 运算符工作原理 =======");
console.log("instanceof 运算符通过检查对象的原型链，判断一个对象是否是某个构造函数的实例。");
console.log("它的工作原理大致是：检查右侧构造函数的 prototype 属性是否出现在左侧对象的原型链上。");
console.log("\n在我们的项目中，instanceof 用于区分不同类型的异常，实现了异常处理的多态性。");